package net.melon.product.inst.service.impl;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.esj.basic.dao.jdbc.JdbcDao;
import net.esj.basic.dao.querybuilder.QueryBuilder;
import net.esj.basic.service.impl.DefaultServiceImpl;
import net.esj.basic.utils.StringUtils;
import net.melon.jdbc.core.RowMapper;
import net.melon.product.inst.service.TypeService;
import net.melon.product.pojo.ProductAttribute;
import net.melon.product.pojo.ProductType;
import net.melon.product.pojo.ProductTypeBrandId;
import net.melon.product.pojo.ProductTypeBrandLink;
import net.melon.product.pojo.ProductTypeSpecificationsId;
import net.melon.product.pojo.ProductTypeSpecificationsLink;
import net.melon.sysres.pojo.SysValue;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service("typeService")
public class TypeServiceImpl extends DefaultServiceImpl implements TypeService {

	@Override
	public void deleteProductType(Long id) {
		ProductType type = get(id, ProductType.class);
		type.setState(-1);
		update(type);
	}

	private static final String LIST_ATTRIBUTR_SQL = "SELECT * FROM ML_PRODUCT_ATTRIBUTE WHERE TYPE_ID = ? AND STATE = 1 ";
	
	@Override
	public List<ProductAttribute> getAttributeListByTypeId(Long id) {
		List<ProductAttribute> list = getDao(JdbcDao.class).getJdbcTemplate().query(LIST_ATTRIBUTR_SQL,
				new RowMapper<ProductAttribute>() {
					@Override
					public ProductAttribute mapRow(ResultSet arg0, int arg1)
							throws SQLException {
						ProductAttribute pa = new ProductAttribute();
						pa.setId(arg0.getLong("ID"));
						pa.setName(arg0.getString("NAME"));
						pa.setRequired(arg0.getInt("REQUIRED"));
						String selectValue = arg0.getString("SELECT_VALUE");
						pa.setSelectValue(selectValue);
						pa.setState(arg0.getInt("STATE"));
						pa.setType(arg0.getInt("TYPE"));
						pa.setTypeId(arg0.getLong("TYPE_ID"));
						pa.setUnit(arg0.getInt("UNIT"));
						if(arg0.getInt("TYPE")==2 && StringUtils.hasText(selectValue)){
							String[] selectValueArr = selectValue.split(",");
							List<SysValue> selectValueList = new ArrayList<SysValue>();
							for(String s : selectValueArr){
								selectValueList.add(new SysValue(s, s));
							}
							pa.setSelectValueList(selectValueList);
						}
						return pa;
					}
				},new Object[]{id});
		
		return list;
	}

	@Override
	public void addAttributeList(List<ProductAttribute> attributes,Long typeId) {
		List<ProductAttribute> list = getAttributeListByTypeId(typeId);
		Map<Long,ProductAttribute> map = new HashMap<Long,ProductAttribute>();
		for(ProductAttribute productAttribute : list){
			productAttribute.setState(-1);
			map.put(productAttribute.getId(), productAttribute);
		}
		for(ProductAttribute p : attributes){
			if(p.getId()==null){
				save(p);
			}else if(map.containsKey(p.getId())){
				p.setState(1);
				map.put(p.getId(), p);
			}
		}
		for(ProductAttribute p : map.values()){
			update(p);
		}
	}

	@Override
	public List<ProductTypeBrandLink> existBrandLinks(Long typeId) {
		QueryBuilder<ProductTypeBrandLink> qb = createQueryBuilder(ProductTypeBrandLink.class);
		qb.eq("type.id", typeId).fetch("type").fetch("brand").eq("state", 1);
		return queryListByQueryBuilder(qb);
	}

	@Transactional
	@Override
	public void addProductTypeBrandLink(List<ProductTypeBrandLink> brandLinks,Long typeId) {
		Map<Long,ProductTypeBrandLink> map = new HashMap<Long,ProductTypeBrandLink>();
		List<ProductTypeBrandLink> list =  getDao(JdbcDao.class).getJdbcTemplate().query(" SELECT * FROM `ml_product_type_brand_link` WHERE `TYPE_ID` = ? ", new RowMapper<ProductTypeBrandLink>() {
			@Override
			public ProductTypeBrandLink mapRow(ResultSet arg0, int arg1)
					throws SQLException {
				ProductTypeBrandLink l = new ProductTypeBrandLink();
				l.setId(new ProductTypeBrandId(arg0.getLong("BRAND_ID"),arg0.getLong("TYPE_ID")));
				l.setState(arg0.getInt("STATE"));
				return l;
			}
		},new Object[]{typeId});
		
		for(ProductTypeBrandLink l : list){
			l.setState(-1);
			map.put(l.getId().getBrandId(), l);
		}
		
		for(ProductTypeBrandLink link : brandLinks){
			if(map.containsKey(link.getId().getBrandId())){
				link.setState(1);
				map.put(link.getId().getBrandId(), link);
			}else{
				link.setState(1);
				save(link);
			}
		}
		for(ProductTypeBrandLink link : map.values()){
			update(link);
		}
	}

	@Override
	public List<ProductTypeSpecificationsLink> exitSpecificationsLinks(Long typeId) {
		QueryBuilder<ProductTypeSpecificationsLink> qb = createQueryBuilder(ProductTypeSpecificationsLink.class);
		qb.eq("type.id", typeId).fetch("type").fetch("specifications").eq("state", 1).OrderByAsc("specifications.order");
		return queryListByQueryBuilder(qb);
	}

	
	@Transactional
	@Override
	public void addProductTypeSpecificationsLink(List<ProductTypeSpecificationsLink> specificationsLinks,Long typeId) {
		Map<Long,ProductTypeSpecificationsLink> map = new HashMap<Long,ProductTypeSpecificationsLink>();
		List<ProductTypeSpecificationsLink> list =  getDao(JdbcDao.class).getJdbcTemplate().query(" SELECT * FROM `ML_PRODUCT_TYPE_SPECIFICATIONS_LINK` WHERE `TYPE_ID` = ? ", new RowMapper<ProductTypeSpecificationsLink>() {
			@Override
			public ProductTypeSpecificationsLink mapRow(ResultSet arg0, int arg1)
					throws SQLException {
				ProductTypeSpecificationsLink l = new ProductTypeSpecificationsLink();
				l.setId(new ProductTypeSpecificationsId(arg0.getLong("SPECIFICATIONS_ID"),arg0.getLong("TYPE_ID")));
				l.setState(arg0.getInt("STATE"));
				return l;
			}
		},new Object[]{typeId});
		
		for(ProductTypeSpecificationsLink l : list){
			l.setState(-1);
			map.put(l.getId().getSpecificationsId(), l);
		}
		
		for(ProductTypeSpecificationsLink link : specificationsLinks){
			if(map.containsKey(link.getId().getSpecificationsId())){
				link.setState(1);
				map.put(link.getId().getSpecificationsId(), link);
			}else{
				link.setState(1);
				save(link);
			}
		}
		for(ProductTypeSpecificationsLink link : map.values()){
			update(link);
		}
	}

	@Override
	public List<ProductType> getProductTypeList() {
		QueryBuilder<ProductType> qb = createQueryBuilder(ProductType.class);
		qb.eq("state", 1);
		return queryListByQueryBuilder(qb);
	}
	
}
